<?php
class system_db {
	
	/**
	 * Use the PROFILER constant in the config of a Zend_Db_Adapter.
	 */
	const PROFILER = 'profiler';
	
	/**
	 * Use the CASE_FOLDING constant in the config of a Zend_Db_Adapter.
	 */
	const CASE_FOLDING = 'caseFolding';
	
	/**
	 * Use the AUTO_QUOTE_IDENTIFIERS constant in the config of a Zend_Db_Adapter.
	 */
	const AUTO_QUOTE_IDENTIFIERS = 'autoQuoteIdentifiers';
	
	/**
	 * Use the ALLOW_SERIALIZATION constant in the config of a Zend_Db_Adapter.
	 */
	const ALLOW_SERIALIZATION = 'allowSerialization';
	
	/**
	 * Use the AUTO_RECONNECT_ON_UNSERIALIZE constant in the config of a Zend_Db_Adapter.
	 */
	const AUTO_RECONNECT_ON_UNSERIALIZE = 'autoReconnectOnUnserialize';
	
	/**
	 * Use the INT_TYPE, BIGINT_TYPE, and FLOAT_TYPE with the quote() method.
	 */
	const INT_TYPE = 0;
	const BIGINT_TYPE = 1;
	const FLOAT_TYPE = 2;
	
	/**
	 * PDO constant values discovered by this script result:
	 *
	 * $list = array(
	 * 'PARAM_BOOL', 'PARAM_NULL', 'PARAM_INT', 'PARAM_STR', 'PARAM_LOB',
	 * 'PARAM_STMT', 'PARAM_INPUT_OUTPUT', 'FETCH_LAZY', 'FETCH_ASSOC',
	 * 'FETCH_NUM', 'FETCH_BOTH', 'FETCH_OBJ', 'FETCH_BOUND',
	 * 'FETCH_COLUMN', 'FETCH_CLASS', 'FETCH_INTO', 'FETCH_FUNC',
	 * 'FETCH_GROUP', 'FETCH_UNIQUE', 'FETCH_CLASSTYPE', 'FETCH_SERIALIZE',
	 * 'FETCH_NAMED', 'ATTR_AUTOCOMMIT', 'ATTR_PREFETCH', 'ATTR_TIMEOUT',
	 * 'ATTR_ERRMODE', 'ATTR_SERVER_VERSION', 'ATTR_CLIENT_VERSION',
	 * 'ATTR_SERVER_INFO', 'ATTR_CONNECTION_STATUS', 'ATTR_CASE',
	 * 'ATTR_CURSOR_NAME', 'ATTR_CURSOR', 'ATTR_ORACLE_NULLS',
	 * 'ATTR_PERSISTENT', 'ATTR_STATEMENT_CLASS', 'ATTR_FETCH_TABLE_NAMES',
	 * 'ATTR_FETCH_CATALOG_NAMES', 'ATTR_DRIVER_NAME',
	 * 'ATTR_STRINGIFY_FETCHES', 'ATTR_MAX_COLUMN_LEN', 'ERRMODE_SILENT',
	 * 'ERRMODE_WARNING', 'ERRMODE_EXCEPTION', 'CASE_NATURAL',
	 * 'CASE_LOWER', 'CASE_UPPER', 'NULL_NATURAL', 'NULL_EMPTY_STRING',
	 * 'NULL_TO_STRING', 'ERR_NONE', 'FETCH_ORI_NEXT',
	 * 'FETCH_ORI_PRIOR', 'FETCH_ORI_FIRST', 'FETCH_ORI_LAST',
	 * 'FETCH_ORI_ABS', 'FETCH_ORI_REL', 'CURSOR_FWDONLY', 'CURSOR_SCROLL',
	 * 'ERR_CANT_MAP', 'ERR_SYNTAX', 'ERR_CONSTRAINT', 'ERR_NOT_FOUND',
	 * 'ERR_ALREADY_EXISTS', 'ERR_NOT_IMPLEMENTED', 'ERR_MISMATCH',
	 * 'ERR_TRUNCATED', 'ERR_DISCONNECTED', 'ERR_NO_PERM',
	 * );
	 *
	 * $const = array();
	 * foreach ($list as $name) {
	 * $const[$name] = constant("PDO::$name");
	 * }
	 * var_export($const);
	 */
	const ATTR_AUTOCOMMIT = 0;
	const ATTR_CASE = 8;
	const ATTR_CLIENT_VERSION = 5;
	const ATTR_CONNECTION_STATUS = 7;
	const ATTR_CURSOR = 10;
	const ATTR_CURSOR_NAME = 9;
	const ATTR_DRIVER_NAME = 16;
	const ATTR_ERRMODE = 3;
	const ATTR_FETCH_CATALOG_NAMES = 15;
	const ATTR_FETCH_TABLE_NAMES = 14;
	const ATTR_MAX_COLUMN_LEN = 18;
	const ATTR_ORACLE_NULLS = 11;
	const ATTR_PERSISTENT = 12;
	const ATTR_PREFETCH = 1;
	const ATTR_SERVER_INFO = 6;
	const ATTR_SERVER_VERSION = 4;
	const ATTR_STATEMENT_CLASS = 13;
	const ATTR_STRINGIFY_FETCHES = 17;
	const ATTR_TIMEOUT = 2;
	const CASE_LOWER = 2;
	const CASE_NATURAL = 0;
	const CASE_UPPER = 1;
	const CURSOR_FWDONLY = 0;
	const CURSOR_SCROLL = 1;
	const ERR_ALREADY_EXISTS = NULL;
	const ERR_CANT_MAP = NULL;
	const ERR_CONSTRAINT = NULL;
	const ERR_DISCONNECTED = NULL;
	const ERR_MISMATCH = NULL;
	const ERR_NO_PERM = NULL;
	const ERR_NONE = '00000';
	const ERR_NOT_FOUND = NULL;
	const ERR_NOT_IMPLEMENTED = NULL;
	const ERR_SYNTAX = NULL;
	const ERR_TRUNCATED = NULL;
	const ERRMODE_EXCEPTION = 2;
	const ERRMODE_SILENT = 0;
	const ERRMODE_WARNING = 1;
	const FETCH_ASSOC = 2;
	const FETCH_BOTH = 4;
	const FETCH_BOUND = 6;
	const FETCH_CLASS = 8;
	const FETCH_CLASSTYPE = 262144;
	const FETCH_COLUMN = 7;
	const FETCH_FUNC = 10;
	const FETCH_GROUP = 65536;
	const FETCH_INTO = 9;
	const FETCH_LAZY = 1;
	const FETCH_NAMED = 11;
	const FETCH_NUM = 3;
	const FETCH_OBJ = 5;
	const FETCH_ORI_ABS = 4;
	const FETCH_ORI_FIRST = 2;
	const FETCH_ORI_LAST = 3;
	const FETCH_ORI_NEXT = 0;
	const FETCH_ORI_PRIOR = 1;
	const FETCH_ORI_REL = 5;
	const FETCH_SERIALIZE = 524288;
	const FETCH_UNIQUE = 196608;
	const NULL_EMPTY_STRING = 1;
	const NULL_NATURAL = 0;
	const NULL_TO_STRING = NULL;
	const PARAM_BOOL = 5;
	const PARAM_INPUT_OUTPUT = -2147483648;
	const PARAM_INT = 1;
	const PARAM_LOB = 3;
	const PARAM_NULL = 0;
	const PARAM_STMT = 4;
	const PARAM_STR = 2;
	
	/**
	 * 
	 * @param array $config
	 * @return system_db_adapter_abstract
	 */
	public static function factory($config = array()) {
		isset($config['type']) ? '' : $config['type'] = 'pdo_mysql';
		isset($config['host']) ? '' : $config['host'] = 'localhost';
		isset($config['port']) ? '' : $config['port'] = 3306;
		isset($config['dbname']) ? '' : $config['dbname'] = 'system';
		isset($config['username']) ? '' : $config['username'] = 'root';
		isset($config['password']) ? '' : $config['password'] = '';
		isset($config['table_prefix']) ? system_db_table::setTablePrefix($config['table_prefix']) : '';
		
		$adapterName = 'system_db_adapter_'.str_replace(' ', '_', strtolower(str_replace('_', ' ', strtolower($config['type']))));
		
		$dbAdapter = new $adapterName($config);
		return self::$adapter = $dbAdapter;
	}
	
	private static $adapter = null;
	
	/**
	 * @return system_db_adapter_abstract
	 * 
	 */
	public static function getAdapter() {
		return self::$adapter;
	}
	public static function setAdapter(system_db_adapter_abstract $adapter) {
		self::$adapter = $adapter;
	}
	
	public static function shortCode($input, $rand = false) {
		$base32 = array (
			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
			'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
			'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
			'y', 'z', '0', '1', '2', '3', '4', '5'
		);
		
		$hex = md5($input);
		$hexLen = strlen($hex);
		$subHexLen = $hexLen / 8;
		$output = array();
		
		for($i = 0; $i < $subHexLen; $i++) {
			$subHex = substr($hex, $i * 8, 8);
			$int = 0x3FFFFFFF & (1 * ('0x' . $subHex));
			$out = '';
			for($j = 0; $j < 6; $j++) {
				$val = 0x0000001F & $int;
				$out .= $base32[$val];
				$int = $int >> 5;
			}
			$output[] = strtoupper($out);
		}
		$index = $rand ? rand(0, count($output) - 1) : 0;
		return $output[$index];
	}
}